
package controllers.auth;

import admin.AdminUser;
import admin.AdminUserLoginToken;
import admin.AdminUserRole;
import cn.hutool.core.convert.Convert;
import controllers.baseAPI.BaseJsonAPI;
import models.base.RequestUtility;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import play.Logger;
import play.cache.Cache;
import play.i18n.Messages;
import play.mvc.Before;
import utils.ConvertUtil;
import utils.GlobalConfig;

/**
 * 认证检查.
 */
public class Secure extends BaseJsonAPI {

    public final static String CACHE_TERMINAL_LOGIN_USER_TAG = "ULC_ADMIN_CACHE_TERMINAL_LOGIN_USER_";


    /**
     * @throws Throwable
     */
    @Before(unless = {"getLoginUserId", "getLoginUser", "getCurrentShop", "getFromHeaderToken", "setCommInfo"})
    public static void filter() throws Throwable {
        String headerToken = RequestUtility.getHeaderIgnoreCase(GlobalConfig.API_HEADER_TOKEN);
        Logger.info("===================headerToken:%s", headerToken);
        AdminUser loginUser = Cache.get(CACHE_TERMINAL_LOGIN_USER_TAG + headerToken, AdminUser.class);
        if (loginUser == null)
            getFromHeaderToken(headerToken);
    }

    /**
     * 获取当前登录用户ID
     *
     * @return
     */
    public static long getLoginUserId() {

        AdminUser terminalUser = getLoginUser();
        if (terminalUser == null)
            return 0;
        return ConvertUtil.toLong(terminalUser.id);
    }

    /**
     * 获取当前登录用户
     *
     * @return
     */
    public static AdminUser getLoginUser() {
        String headerToken = RequestUtility.getHeaderIgnoreCase(GlobalConfig.API_HEADER_TOKEN);
        AdminUser loginUser = Cache.get(CACHE_TERMINAL_LOGIN_USER_TAG + headerToken, AdminUser.class);
        if (loginUser == null)
            loginUser = getFromHeaderToken(headerToken);
        return loginUser;
    }





    /**
     * 从header获取 token 从而获取登录用户信息
     *
     * @return
     */
    private static AdminUser getFromHeaderToken(String headerToken) {
        headerToken = StringUtils.isNotBlank(headerToken) ? headerToken : session.get("HEADER_TOKEN");
        Logger.info("==============headerToken:%s", headerToken);
        String token = headerToken.substring(0, 16);
        Long loginUserId = ConvertUtil.toLong(headerToken.substring(16));
        Logger.info("==============token:%s", token);
        Logger.info("==============loginUserId:%s", loginUserId);

        AdminUserLoginToken terminalLoginToken = AdminUserLoginToken.findByuserAndToken(loginUserId, ConvertUtil.toSHA512(token));
        if (terminalLoginToken == null)
            renderFailMessage(401, "token 失效，请重新登录");

        AdminUser loginUser = terminalLoginToken.adminUser;
        Cache.set(CACHE_TERMINAL_LOGIN_USER_TAG + headerToken, loginUser, "15mn");

        return loginUser;
    }



    /**
     * 已经确定好controllerName 和 activityName
     * @param controllerName
     * @param activityName
     * @return
     */
    public static Boolean checkAuth(String controllerName , String activityName) {

        System.out.println("-----------------------------");
        System.out.println("controllerName:"+controllerName);
        System.out.println("activityName:"+activityName);
        AdminUser loginUser = getLoginUser(); //获取登录用户
        System.out.println("loginUser:"+loginUser);

        if(loginUser == null){
            renderWarnMessage(401, Messages.get("flash.warn.no-login"));
        }

        //查询用户是否拥有该功能的操作授权
        String sqlSelect = "select count(0) as user_number " +
                "    from admin_user_role a " +
                "    left join admin_role_operate b on a.role_id = b.role_id  " +
                "    left join admin_business c on b.business_id = c.id  " +
                "    where a.user_id = %s and c.controller_name = '%s' and c.action_name = '%s'" ;
        //防sql注入
        sqlSelect = StringEscapeUtils.escapeSql(String.format(sqlSelect , loginUser.getId(),  controllerName , activityName));

        return Convert.toInt(AdminUserRole.em().createNativeQuery(sqlSelect).getSingleResult()) > 0;

    }

}
